/// 
/// MaDAson - Toolkit for Model Driven Software Development
/// 
/// Copyright [2006] Marcus Lankenau
/// 
/// Licensed under the Apache License, Version 2.0 (the "License");
/// you may not use this file except in compliance with the License.
/// You may obtain a copy of the License at
///  
///     http://www.apache.org/licenses/LICENSE-2.0
///  
/// Unless required by applicable law or agreed to in writing, software
/// distributed under the License is distributed on an "AS IS" BASIS,
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
/// See the License for the specific language governing permissions and
/// limitations under the License.
/// 

using System;
using System.Collections.Generic;
using System.Text;
using System.Collections;

namespace Madason.MetaModel.Validation
{
	public enum ValidationIssueSeverity
	{
		Warning,
		Error
	}

	/// <summary>
	/// Issue in validation of model
	/// </summary>
	public class ValidationIssue
	{
		private string message;
		private ValidationIssueSeverity severity;
		private ModelElement modelElement;


		/// <summary>
		/// error/warning message of issue
		/// </summary>
		public string Message
		{
			get { return message; }
			set { message = value; }
		}

		
		/// <summary>
		/// Severity of issue
		/// </summary>
		public ValidationIssueSeverity Severity
		{
			get { return severity; }
			set { severity = value; }
		}


		
		/// <summary>
		/// Model Element, the issue occured in
		/// </summary>
		public ModelElement ModelElement
		{
			get { return modelElement; }
			set { modelElement = value; }
		}


		public ValidationIssue(string message, ValidationIssueSeverity severity, ModelElement modelElement)
		{
			this.message = message;
			this.severity = severity;
			this.modelElement = modelElement;
		}

		public override string ToString()
		{
			string place = "";
			if (modelElement is Namespace)
				place = (modelElement as Namespace).FullName;
			else if (modelElement is Class)
				place = (modelElement as Class).ExplicitName;
			else if (modelElement is Attribute)
			{
				Attribute attr = modelElement as Attribute;
				place = attr.Class.ExplicitName + "::" + attr.Name;
			}
			else if (modelElement is Operation)
			{
				Operation op = modelElement as Operation;
				place = op.Class.ExplicitName + "::" + op.Name + "()";
			}
			else if (modelElement is Association)
			{
				Association assoc = modelElement as Association;
				place = assoc.Class.ExplicitName + "->" + assoc.TargetClass.Name;
			}
			else if (modelElement is StateTransition)
			{
				StateTransition trans = modelElement as StateTransition;
				place = trans.Source.Name + "->" + trans.Target.Name;
			}

			string sev = (Severity == ValidationIssueSeverity.Error) ? "Error" : "Warning";

			return sev + " in " + place + ": " + Message;
		}
	}

	/// <summary>
	/// List of Validation Issues
	/// </summary>
	public class ValidationIssueList : ArrayList
	{
		public ValidationIssue this[int i]
		{
			get
			{
				return base[i] as ValidationIssue;
			}
		}

		/// <summary>
		/// This is for use in unit-tests
		/// </summary>
		/// <param name="msg"></param>
		/// <returns></returns>
		public bool ContainsMessage(string msg)
		{
			foreach (ValidationIssue issue in this)
				if (issue.Message == msg)
					return true;
			return false;
		}

		public bool ContainsErrors()
		{
			foreach (ValidationIssue issue in this)
				if (issue.Severity == ValidationIssueSeverity.Error)
					return true;
			return false;
		}
	}
}
